# -*- coding: UTF-8 -*-
"""常用工具类"""
import math
import re
import random
import time
from datetime import datetime
from dateutil.tz import tz


def half_split_int_range(start_num: int, end_num: int, must_int: bool = True):
    """
    将两个数字范围分割成等长的两个区间
    :param s:
    :param err:
    :return:
    """
    try:
        if start_num < end_num:
            half_num = start_num + (end_num - start_num) / 2
            # 向下取整转整数
            floor_half_num = math.floor(half_num)
            if floor_half_num <= start_num:
                if not must_int:
                    # [3, 4] ==> [(3, 3.5), (3.5, 4)]
                    return [(start_num, half_num), (half_num, end_num)]
                else:
                    return []
            else:
                return [(start_num, floor_half_num), (floor_half_num, end_num)]
        return []
    except ValueError:
        return []


def half_split_float_range(start_num: float, end_num: float):
    """
    将两个数字范围分割成等长的两个区间
    :param start_num:
    :param end_num:
    :return:
    """
    try:
        if start_num < end_num:
            half_num = start_num + (end_num - start_num) / 2
            return [(start_num, half_num), (half_num, end_num)]
        return []
    except ValueError:
        return []


def parse_number(s, err=-1):
    """
    解析数字，如果解析失败返回默认值
    :param s:
    :param err:
    :return:
    """
    try:
        if isinstance(s, str):
            s = s.replace('¥', '').replace('￥', '').replace(',', '').replace('元', '').strip()
            return float(s)
        return s
    except ValueError:
        return err


def parse_int(s, err=-1):
    """
    解析整型数字，如果解析失败返回默认值
    :param s:
    :param err:
    :return:
    """
    try:
        if isinstance(s, str):
            s = s.replace('¥', '').replace('￥', '').replace(',', '').replace('元', '').strip()
        return int(s)
    except ValueError:
        return err


def parse_time(time_str, fmt='%Y-%m-%d %H:%M:%S', tz_str='Asia/Shanghai'):
    """
    将时间字符串解析成本地时间
    :param time_str:
    :param fmt:
    :param tz_str:
    :return:
    """
    if time_str:
        return datetime.strptime(time_str, fmt).astimezone(tz.gettz(tz_str))


def parse_timestamp(time_str, tz_str='Asia/Shanghai'):
    """
    将时间戳解析成本地时间(自动截断毫秒)
    :param time_str:
    :param tz_str:
    :return:
    """
    if time_str:
        # 1576839034000
        if len(str(time_str)) > 10:
            # 截取掉毫秒
            time_str = str(time_str)[:-3]
        return datetime.fromtimestamp(int(time_str)).astimezone(tz.gettz(tz_str))


def parse_date(time_str, fmt='%Y-%m-%d', tz_str='Asia/Shanghai'):
    """
    将日期字符串解析成本地日期
    :param time_str:
    :param fmt:
    :param tz_str:
    :return:
    """
    if time_str:
        return datetime.strptime(time_str, fmt).astimezone(tz.gettz(tz_str))


def format_time(dt, fmt='%Y-%m-%d %H:%M:%S'):
    """
    将时间格式化为字符串
    :param dt:
    :param fmt:
    :return:
    """
    if dt:
        return dt.strftime(fmt)


def format_date(dt, fmt='%Y-%m-%d'):
    """
    将时间格式化为字符串
    :param dt:
    :param fmt:
    :return:
    """
    if dt:
        return dt.strftime(fmt)


def get_time_stamp13():
    # 生成13时间戳   eg:1540281250399895
    datetime_now = datetime.now()

    # 10位，时间点相当于从UNIX TIME的纪元时间开始的当年时间编号
    date_stamp = str(int(time.mktime(datetime_now.timetuple())))

    # 3位，微秒
    data_microsecond = str("%06d" % datetime_now.microsecond)[0:3]

    date_stamp = date_stamp + data_microsecond
    return int(date_stamp)


def join_dict(kv):
    """
    将dict键值对拼接成字符串
    :param kv:
    :return:
    """
    s = ''
    for (k, v) in kv.items():
        s += k + ': ' + v + '\r\n'
    return s.strip()


def random_code(n=5, alpha=True):
    """
    生成验证码
    :param n:
    :param alpha:
    :return:
    """
    s = ''  # 创建字符串变量,存储生成的验证码
    for i in range(n):  # 通过for循环控制验证码位数
        num = random.randint(0, 9)  # 生成随机数字0-9
        if alpha:  # 需要字母验证码,不用传参,如果不需要字母的,关键字alpha=False
            upper_alpha = chr(random.randint(65, 90))
            lower_alpha = chr(random.randint(97, 122))
            num = random.choice([num, upper_alpha, lower_alpha])
        s = s + str(num)
    return s


def match_ip_port(txt):
    """
    解析IP和端口
    :param txt:
    :return:
    """
    # /frontBrands/getBrandsAndProductInfos.action?orderBy=normal&shopInfoId=1
    if txt:
        arr = re.findall(r'(?:(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])\.){3}(?:[0,1]?\d?\d|2[0-4]\d|25[0-5]):\d{0,5}',
                         txt.strip())
        if len(arr):
            return arr[0].strip()
    return ''


def list_of_groups(init_list, childern_list_len):
    """
    列表分割成多个小列表
    :param init_list:
    :param childern_list_len:
    :return:
    """
    list_of_groups = zip(*(iter(init_list),) * childern_list_len)
    end_list = [list(i) for i in list_of_groups]
    count = len(init_list) % childern_list_len
    end_list.append(init_list[-count:]) if count != 0 else end_list
    return end_list


if __name__ == '__main__':
    print(half_split_float_range(3.5, 6.5))
    print(half_split_int_range(3, 6))
    print(half_split_int_range(3, 5))
    print(half_split_int_range(3, 4))
